home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 7604 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.2 KB  |  135 lines

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: What is &Variable (declared as: char Variable[10])?
  5. Date: 25 Feb 1996 17:16:13 -0800
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4gr1ktINNqin@keats.ugrad.cs.ubc.ca>
  8. References: <4gqpa1$3h9@alcor.usc.edu>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <4gqpa1$3h9@alcor.usc.edu>, Abu Wawda <wawda@alcor.usc.edu> wrote:
  12. >I'm having trouble understanding what the address of a static array
  13. >is.
  14.  
  15. Read K&R, twice if you have to.
  16.  
  17. >For example, if I declare a variable called myarray as:
  18. >    char myarray[10];
  19. >then what could &myarray possibly mean? myarray is not a pointer, so
  20.  
  21. No, myrray is not a pointer. But the _expression_ myarray yields a pointer to
  22. the first element of the array object myarray. Thus, a statement like this is
  23. legal:
  24.  
  25.     char *ptr = myarray;     /* provided myarray is decl'd in scope    */
  26.  
  27. >&myarray could not possibly be the address of the variable myarray
  28. >(like it would be if I did char* myarray and then asked for &myarray).
  29.  
  30. Yes, &myarray is the address of the variable myarray. It is a pointer, whose
  31. type is ``pointer to array of ten characters'', or, if you will: char (*)[10].
  32.  
  33. >Functions such as scanf() allow the following:
  34. >
  35. >    char myarray[10];
  36. >
  37. >    scanf("%s",&myarray);
  38.  
  39. This wrong. The expression &myarray is a pointer to an array of ten characters,
  40. as I just mentioned. Scanf requires the %s conversion parameter to be matched
  41. by a string, which is pointer to a character, not to an array of ten
  42. characters. Also, scanf() will overrun your array if the user (or input stream)
  43. causes more than 9 characters of input to be interpreted as the string. Use
  44. "%9s".
  45.  
  46. Don't be fooled by the fact that the above works. It just so happens that
  47. myarray and &myarray are both expressions that yield the same pointer. But the
  48. two pointers have a different type. The compiler will not warn you of this
  49. error unless it is very sophisticated in that it can analyze scanf() format
  50. strings and match them against argument types.
  51.  
  52. >but I don't understand what scanf() could possibly be taking in the
  53. >second parameter. It can't be: char** since myarray is not a
  54. >pointer.
  55.  
  56. No, what you are giving to scanf is a char(*)[10]. Note the parentheses around
  57. *. Without them, you have char *[10], which is an array of ten character
  58. pointers, not a pointer to an array of ten characters.
  59.  
  60.  I CAN understand how the following would work:
  61. >
  62. >    char* myarray;
  63. >
  64. >    myarray = (char*) malloc(10);
  65. >    scanf("%s",&myarray);
  66.  
  67. This is extremely wrong, and will yield undefined results.
  68.  
  69. >Then scanf() is simply taking a char** (pointer to a character
  70. >pointer, or in other words the address of the pointer myarray) in its
  71. >second paremeter. However, if I write my own function like this:
  72.  
  73. scanf() does not manufacture string pointers. scanf does _not_ dynamically
  74. allocate strings. You have to provide the storage, and you pass a simple
  75. character pointer. The above is correct up to the malloc. But the scanf() call
  76. should be:
  77.  
  78.     scanf("%9s",myarray);
  79.  
  80. By the way, you should not call it myarray in this case. The name of the
  81. variable is misleading. It is not an array, but a character pointer, which
  82. points to a dynamically allocated array. If you take its address, &myarray, you
  83. have a genuine char **, which is not a suitable argument to scanf() by any
  84. means.
  85.  
  86. It just so happens that an array of type T, and a pointer to type T, can both
  87. be used in array expressions using the [] postfix operator, but a pointer
  88. variable is not an array object.
  89.  
  90. >    void func(char** p)
  91. >    {
  92. >        // do something here
  93.  
  94. That is not a standard C comment. Avoid C++ comments in standard C programming.
  95.  
  96. >    }    
  97. >
  98. >I cannot pass &myarray if I declare it as: char myarray[10]. So how do
  99. >this work? Thanks in advance,
  100.  
  101. It cannot work that way. You want to modify the address of the array. However,
  102. the address of an array is not modifiable. The above routine can only be used
  103. with character pointers. If I have a character pointer, char *p, I can
  104. send its address to the function by doing func(&p), and func() is free to
  105. modify the value of p (by assigning to *p). However, this cannot be done with
  106. arrays. Arrays are not pointer variables, but names of storage which collapse
  107. into addresses when they are used in expressions.
  108.  
  109. The only kind of array you could pass to func() would be a string vector:
  110.  
  111.     char *svec[] = { "Alpha", "Betta", "Gamma", 0 };
  112.  
  113. The expression "svec" collapses into a pointer to the first element. Since the
  114. first element is a string (char *), the type of the expression svec is
  115. a char **. If you pass this to func, again, func() can only modify the
  116. character pointer referenced by svec---in other words, the character pointer
  117. svec[0], svec[1] and so forth. Svec itself can never be modified. So you have a
  118. choice. Pass to func() either a pointer to a single character pointer, or a
  119. pointer to a whole _array_ of these things.
  120.  
  121. If you are expecting an array, you may wish to declare the function as
  122.  
  123.     void func(char *a[])
  124.  
  125. to make this clear.
  126.  
  127. However, this is exactly the same as writing char **a. In parameter
  128. declarations, all arrays silently turn into pointers. This is another fact of
  129. C, which complements the way in which array names turn into pointers inside
  130. expressions.
  131.  
  132.  
  133. -- 
  134.  
  135.